package com.ruoyi.common.datapermission.rule.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryTable;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.table.TableInfo;
import com.mybatisflex.core.table.TableInfoFactory;
import com.ruoyi.common.datapermission.config.AuthProperties;
import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.system.api.permission.dto.DeptDataPermissionRespDTO;
import com.ruoyi.system.domain.table.SysUserTableDef;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

import static com.mybatisflex.core.constant.SqlConsts.*;

/**
 * 用户数据权限实现类
 */
@Slf4j
public class UserDataPermissionRuleImpl extends AbstractDataPermissionRuleImpl {
    @Override
    public void dealDataPermissionSQL(QueryWrapper queryWrapper, List<QueryTable> queryTables) {
        if (CollectionUtil.isEmpty(queryTables)) {
            log.warn("没有查询的表信息");
            return;
        }
        Map<String, String> tableConfig = getTableConfig();
        if (tableConfig == null) {
            return;
        }
        queryTables.forEach(queryTable -> {
            String tableName = queryTable.getName();
            String column = tableConfig.get(tableName);
            if (StrUtil.isBlank(column)) {
                log.warn("数据表【{}】未配置过滤字段", tableName);
                return;
            }
            DeptDataPermissionRespDTO deptDataPermissionRCheckedData = getDeptDataPermissionRespDTO();
            Boolean all = deptDataPermissionRCheckedData.getAll();
            if (all != null && all) {
                return;
            }
            Boolean self = deptDataPermissionRCheckedData.getSelf();
            QueryColumn queryColumn = getQueryColumn(queryTable, column);
            if (queryColumn == null) {
                log.warn("数据表【{}】不存在字段【{}】", tableName, column);
                return;
            }
            if (self != null && self) {
                queryWrapper.and(queryColumn.eq(LoginHelper.getUserId()));
            }
            queryWrapper.and(queryColumn.in(buildUserCondition(deptDataPermissionRCheckedData)));
        });
        //log.info("用户数据权限过滤后的SQL：{}", queryWrapper.toSQL());
    }

    /**
     * 获取表数据权限配置
     * @return
     */
    private Map<String, String> getTableConfig() {
        List<AuthProperties.AuthConfig> configs = authProperties.getConfigs();
        log.info("用户数据权限配置：{}", JSONObject.toJSONString(configs));
        AuthProperties.AuthConfig authConfig = configs.stream().filter(conf -> authType().equals(conf.getRule())).findFirst().orElse(null);
        if (authConfig == null) {
            log.warn("用户数据权限未配置");
            return null;
        }
        if (!authConfig.isEnable()) {
            log.warn("用户数据权限未开启");
            return null;
        }
        Map<String, String> tableConfig = authConfig.getTableConfigs();
        if (MapUtil.isEmpty(tableConfig)) {
            log.warn("用户数据权限字段未配置");
            return null;
        }
        return tableConfig;
    }

    /**
     * 构建用户过滤条件
     * @param deptDataPermissionRCheckedData
     * @return
     */
    private QueryWrapper buildUserCondition(DeptDataPermissionRespDTO deptDataPermissionRCheckedData) {
        return QueryWrapper.create().select(SysUserTableDef.SYS_USER.USER_ID).from(SysUserTableDef.SYS_USER).where(SysUserTableDef.SYS_USER.DEPT_ID.in(deptDataPermissionRCheckedData.getDeptIds()));
    }

    @Override
    public void dealDataPermissionSQL(String schema, String tableName, StringBuilder sql) {
        TableInfo tableInfo = TableInfoFactory.ofTableName(tableName);
        dealDataPermissionSQL(tableInfo, sql);
    }

    @Override
    public void dealDataPermissionSQL(TableInfo tableInfo, StringBuilder sql) {
        Map<String, String> tableConfig = getTableConfig();
        if (tableConfig == null) {
            return;
        }
        String tableName = tableInfo.getTableName();
        String column = tableConfig.get(tableName);
        if (StrUtil.isBlank(column)) {
            log.warn("表【{}】未配置过滤字段", tableName);
            return;
        }
        if (!ArrayUtil.contains(tableInfo.getAllColumns(), column)) {
            log.warn("表【{}】不存在字段【{}】", tableName, column);
            return;
        }
        DeptDataPermissionRespDTO deptDataPermissionRCheckedData = getDeptDataPermissionRespDTO();
        Boolean all = deptDataPermissionRCheckedData.getAll();
        if (all != null && all) {
            return;
        }
        Boolean self = deptDataPermissionRCheckedData.getSelf();
        if (self != null && self) {
            sql.append(AND).append(column).append(EQUALS).append(LoginHelper.getUserId());
        }
        sql.append(AND).append(column).append(IN).append(BRACKET_LEFT).append(buildUserCondition(deptDataPermissionRCheckedData).toSQL()).append(BRACKET_RIGHT);
        //log.info("用户数据权限过滤后的SQL：{}", sql);
    }

    @Override
    public String authType() {
        return "userAuth";
    }
}
